package opengraph.impl

import opengraph.api.OpenGraphMeta

abstract class OpenGraphData<T>(meta: OpenGraphMeta) {
    abstract val content:T?
}

class BasicMeta(
    meta: OpenGraphMeta
) : OpenGraphData<Unit>(meta) {
    val title: String? = meta.find<List<String>?>("@og.title:")?.firstOrNull()
    val type: String? = meta.find<List<String>?>("@og.type:")?.firstOrNull()
    val image: ImageMeta? = meta.find<OpenGraphMeta?>("@og.image")?.run { ImageMeta(this) }
    val url: String? = meta.find<List<String>?>("@og.url:")?.firstOrNull()
    override val content: Unit = Unit

    override fun toString(): String {
        return "BasicMeta(title=$title, type=$type, image=$image, url=$url)"
    }


}

class DefaultMeta(
    meta: OpenGraphMeta
) : OpenGraphData<Unit>(meta) {
    val title: String? = meta.find<List<String>?>("title:")?.firstOrNull()
    val description: String? = meta.find<List<String>?>("description:")?.firstOrNull()
    val icon: String? = meta.find<List<String>?>("icon:")?.firstOrNull()
    override val content: Unit = Unit
    override fun toString(): String {
        return "DefaultMeta(title=$title, description=$description, icon=$icon)"
    }


}

class ImageMeta(
    private val meta: OpenGraphMeta
) : OpenGraphData<String>(meta) {
    var url: String? = meta.find<List<String>?>("url:")?.firstOrNull()
    var secureUrl: String? = meta.find<List<String>?>("secure_url:")?.firstOrNull()
    val type: String? = meta.find<List<String>?>("type:")?.firstOrNull()
    val width: Int? = meta.find<List<String>?>("width:")?.firstOrNull()?.toIntOrNull()
    val height: Int? = meta.find<List<String>?>("height:")?.firstOrNull()?.toIntOrNull()
    val alt: String? = meta.find<List<String>?>("alt:")?.firstOrNull()
    override val content: String?
        get() = meta.content.firstOrNull()

    override fun toString(): String {
        return "ImageMeta(content=$content, url=$url, secureUrl=$secureUrl, type=$type, width=$width, height=$height, alt=$alt)"
    }

}


fun OpenGraphMeta.basic(): BasicMeta {
    return BasicMeta(this)
}

fun OpenGraphMeta.def(): DefaultMeta {
    return DefaultMeta(this)
}
